package org.sampleSpringFramework.mvc;

import org.sampleSpringFramework.aop.AspectWeaver;
import org.sampleSpringFramework.core.BeanContainer;
import org.sampleSpringFramework.inject.DependencyInjector;
import org.sampleSpringFramework.mvc.processor.RequestProcessor;
import org.sampleSpringFramework.mvc.processor.RequestProcessorChain;
import org.sampleSpringFramework.mvc.processor.impl.ControllerRequestProcessor;
import org.sampleSpringFramework.mvc.processor.impl.JspRequestProcessor;
import org.sampleSpringFramework.mvc.processor.impl.PreRequestProcessor;
import org.sampleSpringFramework.mvc.processor.impl.StaticResourceRequestProcessor;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 让该Servlet拦截所有的请求，如果是'/'，由于其优先级最低，则当访问的是jsp页面，或者其他静态资源，如.jpg文件时，
 * 不会被该servlet拦截，所以要配置成/*
 */
@WebServlet("/*")
public class DispatcherServlet extends HttpServlet {

	/**
	 * 维护责任链
	 */
		private List<RequestProcessor> processorList = new ArrayList<>();

		/**
		 * 自研框架服务的初始化
		 * @throws ServletException Servlet初始化过程出现异常
		 */
		@Override
		public void init() throws ServletException {
		// 1、初始化容器
		// （1）创建Bean容器
		BeanContainer beanContainer = BeanContainer.getInstance();
		// （2）加载指定package路径下标记了controller、service、repository、aspect注解的Bean
		beanContainer.loadBeans("com.gill");
		// （3）进行动态代理，执行AOP（让代理类替换目标类成功，才对外提供服务）
		new AspectWeaver().doAop();
		// （4）进行依赖注入，执行IOC
		new DependencyInjector().doIoc();
		// 2、初始化责任链处理器（责任链顺序，按照请求处理的时间成本，从成本较小，到成本较大排序）
		processorList.add(new PreRequestProcessor());
		processorList.add(new StaticResourceRequestProcessor(getServletContext()));
		processorList.add(new JspRequestProcessor(getServletContext()));
		processorList.add(new ControllerRequestProcessor());
	}

	/**
	 * 处理请求
	 * @param req 请求
	 * @param resp 响应
	 * @throws ServletException Servlet处理异常
	 * @throws IOException IO异常
	 */
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// 1、创建责任链
		RequestProcessorChain requestProcessorChain = new RequestProcessorChain(this.processorList.iterator(),req,resp);
		// 2、调用责任链中的请求处理器处理请求
		requestProcessorChain.doRequestProcessorChain();
		// 3、调用责任链中的请求处理器进行渲染
		requestProcessorChain.doRender();
	}
}
